package paidaxing.blog.post.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import paidaxing.blog.common.result.PageResult;
import paidaxing.blog.post.dto.CategoryDTO;
import paidaxing.blog.post.dto.PostDTO;
import paidaxing.blog.post.dto.request.CategoryRequestDTO;
import paidaxing.blog.post.dto.request.PostQueryRequest;
import paidaxing.blog.post.entity.Categories;
import paidaxing.blog.post.mapper.CategoriesDao;
import paidaxing.blog.post.service.CategoriesService;
import paidaxing.blog.post.utils.PostConverter;
import paidaxing.blog.post.utils.RequestConverter;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 分类服务实现类
 */
@Service("categoriesService")
public class CategoriesServiceImpl implements CategoriesService {
    @Autowired
    private CategoriesDao categoriesDao;

    @Override
    public PageResult<CategoryDTO> listCategories(Integer page, Integer size) {
        PageRequest pageRequest = PageRequest.of(page - 1, size);
        long total = categoriesDao.count();
        int offset = (int) pageRequest.getOffset();
        int limit = pageRequest.getPageSize();
        List<Categories> list = categoriesDao.queryAllByLimit(offset, limit);
        Page<Categories> categoryPage = new PageImpl<>(list, pageRequest, total);
        
        List<CategoryDTO> categoryDTOList = categoryPage.getContent().stream()
                .map(PostConverter::toCategoryDTO)
                .collect(Collectors.toList());
        
        PageResult<CategoryDTO> pageResult = new PageResult<>();
        pageResult.setPageNo(page);
        pageResult.setPageSize(size);
        pageResult.setTotal((int) categoryPage.getTotalElements());
        pageResult.setRecords(categoryDTOList);
        
        return pageResult;
    }

    @Override
    public CategoryDTO createCategory(CategoryRequestDTO categoryRequestDTO) {
        CategoryDTO categoryDTO = RequestConverter.toCategoryDTO(categoryRequestDTO);
        
        Date now = new Date();
        Categories categories = new Categories();
        categories.setName(categoryDTO.getName());
        categories.setSlug(categoryDTO.getSlug());
        categories.setDescription(categoryDTO.getDescription());
        categories.setParentId(categoryDTO.getParentId());
        categories.setOrderNum(categoryDTO.getOrderNum());
        categories.setPostCount(0);
        categories.setCreatedAt(now);
        categories.setUpdatedAt(now);
        categories.setDeleted(0);

        categoriesDao.insert(categories);
        
        return PostConverter.toCategoryDTO(categories);
    }
    
    @Override
    public CategoryDTO updateCategory(Long id, CategoryRequestDTO categoryRequestDTO) {
        Categories existingCategory = categoriesDao.queryById(id);
        if (existingCategory == null) {
            return null;
        }

        CategoryDTO categoryDTO = RequestConverter.toCategoryDTO(categoryRequestDTO);

        existingCategory.setName(categoryDTO.getName());
        existingCategory.setSlug(categoryDTO.getSlug());
        existingCategory.setDescription(categoryDTO.getDescription());
        existingCategory.setParentId(categoryDTO.getParentId());
        existingCategory.setOrderNum(categoryDTO.getOrderNum());
        existingCategory.setUpdatedAt(new Date());

        categoriesDao.update(existingCategory);

        return PostConverter.toCategoryDTO(existingCategory);
    }
    
    @Override
    public boolean deleteCategory(Long id) {
        Categories existingCategory = categoriesDao.queryById(id);
        if (existingCategory == null) {
            return false;
        }

        return categoriesDao.deleteById(id) > 0;
    }
    
    @Override
    public PageResult<PostDTO> getPostsByCategory(Long categoryId, PostQueryRequest queryRequest) {
        Categories category = categoriesDao.queryById(categoryId);
        if (category == null) {
            PageResult<PostDTO> emptyResult = new PageResult<>();
            emptyResult.setPageNo(queryRequest.getPageNo());
            emptyResult.setPageSize(queryRequest.getPageSize());
            emptyResult.setTotal(0);
            emptyResult.setRecords(java.util.Collections.emptyList());
            return emptyResult;
        }
        
        PageRequest pageRequest = PageRequest.of(queryRequest.getPageNo() - 1, queryRequest.getPageSize());
        
        List<paidaxing.blog.post.entity.Posts> postsList = 
            categoriesDao.selectPostsByCategoryId(categoryId, pageRequest);
        
        long total = categoriesDao.countPostsByCategoryId(categoryId);
        
        List<PostDTO> postDTOList = postsList.stream().map(post -> {
            PostDTO postDTO = new PostDTO();
            postDTO.setId(post.getId());
            postDTO.setTitle(post.getTitle());
            postDTO.setExcerpt(post.getExcerpt());
            postDTO.setCoverImage(post.getCoverImage());
            postDTO.setStatus(post.getStatus());
            postDTO.setViewCount(post.getViewCount());
            postDTO.setLikeCount(post.getLikeCount());
            postDTO.setCommentCount(post.getCommentCount());
            postDTO.setIsTop(post.getIsTop());
            postDTO.setIsRecommend(post.getIsRecommend());
            postDTO.setUserId(post.getUserId());
            postDTO.setCategoryId(post.getCategoryId());
            postDTO.setPublishedAt(post.getPublishedAt());
            postDTO.setCreatedAt(post.getCreatedAt());
            postDTO.setUpdatedAt(post.getUpdatedAt());
            return postDTO;
        }).collect(Collectors.toList());
        
        PageResult<PostDTO> pageResult = new PageResult<>();
        pageResult.setPageNo(queryRequest.getPageNo());
        pageResult.setPageSize(queryRequest.getPageSize());
        pageResult.setTotal((int) total);
        pageResult.setRecords(postDTOList);
        
        return pageResult;
    }
}